package com.bcx.wind.workflow.imp.cmd.managercmd;

import com.bcx.wind.workflow.access.QueryFilter;
import com.bcx.wind.workflow.access.TaskFilter;
import com.bcx.wind.workflow.core.constant.ProcessStatus;
import com.bcx.wind.workflow.entity.WindProcess;
import com.bcx.wind.workflow.entity.WindProcessModule;
import com.bcx.wind.workflow.interceptor.Command;
import com.bcx.wind.workflow.interceptor.CommandContext;
import com.bcx.wind.workflow.pojo.ProcessModule;
import com.bcx.wind.workflow.support.Assert;

import java.util.List;

import static com.bcx.wind.workflow.message.ErrorCode.USER_MSG_NOT_FOUND;

/**
 * 通过指定的用户以及系统 查询所有流程定义模块 以及所属的流程定义，以及附带的待办任务数量
 *
 * 简称 查询指定任务的待办事宜流程数据
 *
 * 采用定时清理缓存器
 *
 * @author zhanglei
 */
public class QueryToDoProcessCommand implements Command<ProcessModule> {

    /**
     * 用户ID
     */
    private String userId;

    /**
     * 系统标识
     */
    private String system;

    /**
     * 执行数据
     */
    private CommandContext commandContext;


    public QueryToDoProcessCommand(String userId,String system){
        this.userId = userId;
        this.system = system;
    }

    @Override
    public ProcessModule executor(CommandContext context) {
        try{
            this.commandContext = context;
            return execute();
        }catch (Exception e){
            context.log(e);
            return null;
        }
    }


    private ProcessModule  execute(){
        Assert.notEmptyError(USER_MSG_NOT_FOUND,this.userId);
        ProcessModule processModule = this.commandContext.getConfiguration().getToDoProcessModuleCache(this.userId,this.system);

        if(processModule == null){
            ProcessModule module = this.commandContext.repositoryService().selectWindProcessModule(this.system);
            addTodoCountToModule(module);
            processModule = module;
            //添加缓存
            this.commandContext.getConfiguration().addToDoProcessModuleCache(this.userId,this.system,processModule);
        }
        return processModule;
    }



    private void addTodoCountToModule(ProcessModule module) {
        WindProcessModule windProcessModule = module.getWindProcessModule();
        String moduleName = windProcessModule.getId();
        QueryFilter filter = new QueryFilter()
                .setProcessModule(moduleName)
                .setSystem(this.system)
                .setStatus(ProcessStatus.RELEASE);
        List<WindProcess> windProcessList = this.commandContext.access().selectProcessList(filter);
        buildChildCount(module,module.getChild(),windProcessList);
    }



    private void buildChildCount(ProcessModule module, List<ProcessModule> child,List<WindProcess> windProcesses) {
        //设置流程定义下当前用户的任务数量
        for(WindProcess windProcess : windProcesses){
            TaskFilter filter = new TaskFilter()
                    .setActor(this.userId)
                    .setProcessId(windProcess.getId());
            long count = this.commandContext.access().selectTaskInstanceCount(filter);
            windProcess.setTaskNumber(count);
        }
        module.setWindProcesses(windProcesses);

        //递归子模块
        for(ProcessModule processModule : child){
            String moduleName =  processModule.getWindProcessModule().getModuleName();
            QueryFilter filter = new QueryFilter()
                    .setProcessModule(moduleName)
                    .setSystem(this.system)
                    .setStatus(ProcessStatus.RELEASE);
            List<WindProcess> windProcessList = this.commandContext.access().selectProcessList(filter);
            buildChildCount(processModule,processModule.getChild(),windProcessList);
        }
    }
}
